{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bd69c263-2846-44cf-a780-d42b56624772",
   "metadata": {},
   "source": [
    "# Introduction to Software Bill Of Materials Dependency Analysis\n",
    "\n",
    "**Note** For a detailed introduction to Software Bill Of Materials, please read [Intro to Software Bill Of Materials](./00-Intro-to-Software-Bill-Of-Materials.ipynb)\n",
    "\n",
    "A Software Bill of Materials (SBOM) contains details about the components and dependencies that make up a piece of software. This includes libraries, frameworks, modules, and more.  Loading SBOM files into a graph provides an efficient mechanism to explore common SBOM use cases such as Dependency Analysis.  Understanding dependencies allows teams to identify security vulnerabilities or licensing issues that may arise from open source or third-party code used in their software. Vulnerable dependencies are a major source of risk.  Dependency analysis provides visibility into all the direct and transitive dependencies used in a project. This allows security, legal, and development teams to gain a comprehensive inventory of the open source being utilized.\n",
    "\n",
    "During development and maintenance, dependency analysis helps prevent out-of-date or vulnerable components from entering the software supply chain. It supports enforcing policies around the usage of open source and third-party code.  When issues are found in upstream dependencies, analysis of SBOMs allows faster remediation as the impacted downstream software products and versions can be quickly identified from their bill of materials. At an organizational-level, SBOMs and dependency analysis support understanding third-party usage, reducing duplicate work, optimizing licensing expenditure, preventing vendor lock-in, and improving software supply chain security.\n",
    "\n",
    "In summary, dependency analysis of SBOMs grants security and transparency into the software supply chain, allowing teams to efficiently mitigate risks introduced through the use of third-party and open source components."
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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8AE5nCUWUZLbBx54wNu92Bxa9vbbb7sb2r59O62vXbvWaYtD2p555hnKcBYMIrgLx0lXrFgx8cJx6OiREAgKAtJnQekp8ekBAhs3bjziiCMiCJHTuHHjl156ycl/7bXXOOEz5h41bKk9e/Y4JdOR2H///d95553DDjvMaeuxxx5r0aIFbXH8NLo2wUaRC3kTLKxiQsACBKTPLOhEiZAoAlu2bClTpkx0aUyul19+eefOnebR2LFjr7jiCuyzNm3amJx58+adf/757opXXXXVsGHDTj31VAjecMMNu3fv5umiRYuaNGlCTseOHbdu3UrO6NGj77rrriuvvLJLly7c9uvX77jjjsMm46wyU4XMV199lRxq3X333WT+/vvvvXv3xgmTR+YaNWoUauz//u//PvroIypyIgwW22+//cZTCpPmGM9/yv77H4LI+++9UkLAdgSkz2zvYcnnQoCzVEqUKOHK+DvZrl07HNzNhq2PP/54/fr1F1xwwbZt25wQG1R00qbOypUrr7/+ehTV7bffPnToUDTK5s2b69Wrh78JsabQRtCk5KZNm+69997//e9/RNiC8iOPPMIs4siRI4mvOHnyZEOKuUSIcLIo5hd1UWlQ27Fjx9/M7bMPbh1opksvvbRChQpXX301lNGvRofNnTuXdEwnFySFbYeIEkLAegQKWi+hBBQCDgIsTRUuXNi5dRIEpD/nnHMw0c4880wmG2vWrIlbP+tqToGYCcwpdAyPXnjhBZa7li5dyizlkCFDWP3CNsJd/uuvv+Zp6dKlp02blj9/frwzWABD5zENeOSRR2JsGZ130003derUiZIYYSzjOUYhOe4LG46dBlWrVmVhjIqcr92sWbMpU6a0b98e73x3SZNGUuSNzleOELAVAdlntvas5IpEgOUoLvRK5IO/7jkJkzjFTOK9+OKLzBZGlMELMSKH2/Lly5vMgw8+mLlKnC9QVNBHn6HMePTtt9/yl1AdplG0EeeuFSxYsEaNGph3pi5/mTA0aTzsEzzFhojDKFEsOew5TEmHlDtRoEABZ0rTna+0ELAVgdi/bVullVxhRgA1w5WTNwcBD5ly5CTM5cuXY/EYoMwaFekvv/wyGjo0kzuT+b26dev+8tfFRB8zgccee6y7wKBBg9asWfP5559zNHbLli2dR85SGQezNWzY0MmPk8COZAby6aefRoOSjlkSZYZKi/lImULASgSkz6zsVgkVG4E4U3AHHnjg5ZdffuONN+LraAyvww8/HJ3x7rvvYmZhV8Wm6MqlIvFHCMmB1mTW8dxzz42wBVFmderUYaaReUXCIjvGE8tvqNL58+cz4Rk/tiQa1Ci/YsWKoXSvueaaSy65BM5dXPybzGly9d8SSgkBuxCQPrOrPyVNXATiu0igG6iNVjM02I98+umnN23aFC8M56xndFWElnIaPOOMM3A+pDxaE9dH5i1RP+7yKMtnn33WqCJawU/ExO+AIJkcmX322Wc7mwSo6K5Lmobw2u/atas524wpR3LMAp7DgzuBjYi87hylhYDdCCgesd39K+n2QuDEE0988skn+btXbtwbfDpYHttvv/3ilvr3IQtgODqya5ttZP/m/pNimQ2Px6OOOgr9REkomylBrC487/Ei+adgjv8pWbx4cWrhOdK5c2c8JyOmPZ2aGIvdunXjr5OjhBCwG4G9FgDsFlXSCQG2GOO1mCd9VrZs2TzhRlR7rpyqEN3/6KOPNk/dxVBsOVWJyDclWYpjqY9tajkpM2ohKf6WEdV1KwQsRkD6zOLOlWiRCDBziGN9ZG4w71FpJmhITuwjKZ79OT1VvhCwDwHpM/v6VBLliACbtxYsWJDj4+A8YKEuV2bZ7ubsBMi1sAoIAQsQkD+IBZ0oERJFoFatWux6TrR0wMsR0AR5Ay6E2BcCeUBA/iB5AEtFg44A+6lx0yCyovVHerLFjbgkOp866CNW/OcJAdlneYJLhYONAF6FTMGxpSzYYiTAPdEdNdmYAE4qYhUC0mdWdaeEyRWB0047bebMmbkWC3oBZCS6Y9ClEP9CIE8ISJ/lCS4VDjwCBJoiOnDgxchNAGR0h9TKrbieCwEbEJA+s6EXJUPiCLD5jHgcCxcuTLxK4Epychv70ohuHDjOxbAQSAUB6bNU0FPdQCJA5MPx48cHkvXEmEY6J6RyYjVUSgjYgID8G23oRcmQJwQIY0+wxARPZskTZZ8U5jg3ttk5MSd9wpXYEALpRkD2WboRFn3fIcAxLuizUaNG+Y4zLxji8Gsi/UuZeYGlaAQMAemzgHWY2PUEAaLUDx8+3BNSfiNCaH+k8xtX4kcIZAAB6bMMgKwmfIcAvn8c0fL888/7jrPUGBo7duxBBx0UP65jai2othDwLwLSZ/7tG3GWVgR69OjRv3//tDaReeJIhFyZb1ctCgE/ICB95odeEA9ZQKB169aE2x88eHAW2k5Pk0Tc59y1Vq1apYe8qAoBvyMg/0a/95D4Sx8CHA/dsGHDlStXci5a+lrJDOUvv/yySpUq7DyrWbNmZlpUK0LAbwhIn/mtR8RPRhHo06fPqlWrxo0bl9FW09DYhRdeWK1aNcRJA22RFALBQED6LBj9JC7ThwAmWseOHQPtEzhixAg8QebNm5c+lERZCPgfAekz//eROEwvAh988AFBsBYvXlynTp30tpQe6nBer169JUuWKMBVegAW1cAgIH+QwHSVGE0TAieccAJ7kDt37vzTTz+lqYn0keWcMziHfymz9IEsykFBQPZZUHpKfKYXgZ49e+IYMnny5PQ24zX1s88+m2Uz+zYeeI2T6IUCAemzUHSzhEwEgcsuu4yw9KNHj06ksB/KdOrUac+ePc8995wfmBEPQiDrCEifZb0LxICPEGjbtm3ZsmUff/xxH/GUAytdunTZsmXLpEmTcniubCEQOgSkz0LX5RI4PgKoNEJG+dxKwzLbtm2blFn8rtTTsCEgf5Cw9bjkzQWBV199ddeuXW3atPGnewgOIKyZMc0oZZZLR+px+BCQPgtfn0vi3BAYM2YMsTY4U+b999/PrWxGn+OaD1c4gGjNLKO4q7GAICB9FpCOEpuZRWDAgAE33nhj3bp1/bOWxqZp9pnddNNN8mbM7FhQa4FBQOtngekqMZp5BNhqff3115cvX/6hhx7KYoxHYjMSNX/jxo1Dhw7VPrPMDwO1GBQEZJ8FpafEZxYQYKv1/PnzmXvkInp9FjjYZx/apfWqVasSzkrKLCtdoEaDgoD0WVB6SnxmDYG+ffui1d59911C12fyCFDaqlGjxpw5c4iaDw9Zk18NC4GAIKD5xoB0lNj0AQJTp04dOHDgDz/80K1bt6uvvjp9HBG/avjw4SVKlGCaUeeZpQ9nUbYMAekzyzpU4qQdgRkzZuAkMnfuXOKJXHTRRfhoeNUkdtj48ePxrmzcuDHx/lu0aOEVZdERAmFAQPosDL0sGb1HYM2aNcwHTpgwYffu3ZhQzZs3b9KkSdGiRfPaErvcmMmcOXPmtGnTiLbVvn37Dh06HHPMMXmlo/JCQAhIn2kMCIGUEMAHEott9uzZLHSxM6x27dr8rVSpEv6QZcqUYc6wcOHCBQoUQO1t376ducrNmzdv2LBh7dq1y5cvX7p06YoVKxo1anTaaae1bNkS95OUWFFlIRBuBKTPwt3/kt5TBNjvvGzZMlTUunXrcK8nviIKDDWGMkOlodhQb6VLl0bVVahQAZfFWrVqscXNUxZETAiEFwHps/D2vSTPDAJEqLriiiueeeaZJGYjM8OhWhECdiAgf307+lFS+BeBBx98cMqUKfz1L4viTAhYgYDsMyu6UUL4FQGMMyYYd+7cWahQoW+++UYmml87SnzZgIDsMxt6UTL4FgHMsj/++AP2+CsTzbfdJMbsQED2mR39KCn8iIBjnBnmZKL5sZPEk0UIyD6zqDMlis8QcIyzIkWKwBomWr9+/XzGo9gRAvYgIPvMnr6UJL5CAOOsZMmSaDLMsq+//pq9aL/99tvPP/+8detWraL5qqfEjDUIyD6zpisliL8QGDVq1L777ksc4a+++grOUGl9+vQhAgj5/mJU3AgBWxCQfWZLT0oOHyOQL59+aD7uHrFmCwKyz2zpSckhBISAEAg3AtJn4e5/SS8EhIAQsAUB6TNbelJyCAEhIATCjYD0Wbj7X9ILASEgBGxBQPrMlp6UHEJACAiBcCMgfRbu/pf0QkAICAFbEJA+s6UnJYcQEAJCINwISJ+Fu/8lvRAQAkLAFgSkz2zpSckhBISAEAg3AtJn4e5/SS8EhIAQsAUB6TNbelJyCAEhIATCjYD0Wbj7X9ILASEgBGxBQPrMlp6UHEJACAiBcCMgfRbu/pf0QkAICAFbEJA+s6UnJYcQEAJCINwISJ+Fu/8lvRAQAkLAFgSkz2zpSckhBISAEAg3AtJn4e5/SS8EhIAQsAUB6TNbelJyCAEhIATCjYD0Wbj7X9ILASEgBGxBQPrMlp6UHEJACAiBcCMgfRbu/pf0QkAICAFbEJA+s6UnJYcQEAJCINwISJ+Fu/8lvRAQAkLAFgSkz2zpSckhBISAEAg3AtJn4e5/SS8EhIAQsAUB6TNbelJyCAEhIATCjYD0Wbj7X9ILASEgBGxBQPrMlp6UHEJACAiBcCMgfRbu/pf0QkAICAFbEJA+s6UnJYcQEAJCINwISJ+Fu/8lvRAQAkLAFgSkz2zpSckhBISAEAg3AtJn4e5/SS8EhIAQsAUB6TNbelJyCAEhIATCjYD0Wbj7X9ILASEgBGxBQPrMlp6UHEJACAiBcCMgfRbu/pf0QkAICAFbEJA+s6UnJYcQEAJCINwISJ+Fu/8lvRAQAkLAFgSkz2zpSckhBISAEAg3AtJn4e5/SS8EhIAQsAUB6TNbelJyCAEhIATCjYD0Wbj7X9ILASEgBGxBIN8ff/xhiyySQwgIASEgBMKLgOyz8Pa9JM8iArt27friiy+SZuB///vfhg0b9DGaNICqaCUC0mdWdquEygMC3bt3z+e6zjrrrE2bNlG/W7duruw/k/Pnzx8/fnxE5pIlS2KW/Oabb9wlK1as+MQTTxi2br/99sMPP/yoo4464ogj+vXrF5PXLl26uKuTpjAl33nnnTJlypQrV658+fLFixcfN25czOrKFAIhRED6LISdLpEjEbj22mt//uvCZlqxYsW9995rStx8881fu666deuSX61aNVfe17Vq1SIzZkny161bB+Hvv/+eAl27dt24ceN777339NNPowV/++23ESNG3HHHHYsWLTLNuf8OHjz4u78uMt966y2Sn3766fr160855RSq/P7777t37x45cuTFF18MQXdFpYVAaBEoGFrJJbgQcBAoVKjQgQceyC1/zzvvvLVr15pHRYsWxRhyipnE/vvvH50ZsyTlixQpYihfcsklN9xwA0bb8uXLS5QoUbp06X333Rdb8MUXX8TMimiC28J/XSa/WLFiBx10EOmxY8dWqFDhP//5j8m/8MILn3zyyWnTptWvX9/k6K8QCDMC0mdh7n3J/jcC2GQTJ07kBk327LPPoiTMg1dfffXbb781aZTQ/fffT3rNmjXXXXedyTz++OOvuuoq0jFLmnxU0S+//EIBzLsaNWpUqVIFOiVLlmzbtu3JJ5/crl07dJuhluvf119/vX379u5i3GLk3XPPPe5MpYVAOBGQPgtnv0vqvRD47LPPmNPbs2cPK2dbtmwpVaqUecySlZlj5NaYWSQOOOCAmjVrmgIsYsUpySOWu6j466+/MsGI8iv417Vq1ao5c+bwaNCgQUxCMnsZbfAZshF/cQNp1qyZO3Pnzp0Qd+coLQRCi4D0WWi7XoL/i0CrVq1YrzL3pLHVGjZsyO2JJ57YqVOnf8v9lcIXA2eNiMyYJSkDWWN+scrVoEEDlOWYMWNq166NWjr11FP79u3bsmVLlsF69+4dQTDmLWt1r7322i233OI8feONN+rUqePcKiEEwoyA/EHC3PuSPQYCaJ2t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kDI5M2bMKF68OM44/L3gggs+/fRT8jmsjgLu68EHH1yyZAk5jzzyiEOK27Vr13I7btw4TOojjzzy4IMP7tSp0/bt28msWLGimwJpFOeoUaOcTAr06dOHjxWHoDvRv39/p2SZMmXMx2j37t0x2Xfv3m1Kvvzyy5TZtGmTu6LSQiAMCEifBbKXjzrqKN651atX50X2+uuvB1IGvzLN2T1nnnnm8OHDt/11HX744TfeeKNhlqAtX7suJ//mm2/GDnMEQkURivOaa6554okn9uzZwyzxggULRowYYQpMmDDBReNrdA/5J5988s8///z9998/88wzY8eOxf3HoRaRuOSSS3777TfoszHx7rvvXr58OVpt48aNo0ePpiT53bp1GzZsGEZ8REXdCgHrEZA+C3AX33vvvbx2u3Tpwhd9gMXwGetAigV86aWXomk40Oe+++477bTTfvjhB9hkCyBWkXMVLlyYzKJFi1522WVsfnfLgYL56aefWOyESJ06dZ566qnatWubAgcddJBDgYTJ3HfffZmWxM2HOeQ777zzoYce2rFjh5ugk2bqksI0jQokE90JkwT8xErbunUrBhwWIUPCKa+EEAgPAgXDI6qVkjJvRnysrl27tmrVCr9HXqBWiplJoT755BNOpHNaRM2gYMwt29uvu+465xHmkUmzj4J5wkmTJjEDbHKYaUTJkckuiyZNmpx11lnVqlUzj5icpKRJ16tXjwjUJu38pTxpDD6IOJlO4r///e9VV12FicbGxBYtWhx33HE8YhicccYZl19++dSpU5ctW1agQAGnvBJCIDwIyD4LfF8feuihr732WsOGDZl7ZO0k8PJkWwAcQJj6c3OBDWRuS5UqxdeDczmuIuRj1fFV8eOPPzoVOaAV1YJtN336dLQOmsY8Qks5FI4++minvJOgQ0mzdOfkuBNUQXude+65aLU33niDyUzz9NFHH6WJ2267jWU/d3mlhUB4EJB9Zklf9+7dm7ckr1T8GvBTsESqbIhRtWpVvg8cm+zbb79FXZnlMTQNnh0xmerQoQPrXo63MKrl888/x5hDuzATSI8MHDgQW426LM41b948JhGTiQVWrly5smXLxizDdCL6jEcYkSz1TZw4EZXJLQtmxx57bIMGDWLWUqYQCAMCss/s6WVmn3C3W79+fbNmzdasWWOPYOmRhAUqzClzMX3nNNK5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"
    }
   },
   "cell_type": "markdown",
   "id": "1e4cf3f8-86e2-48f1-836a-06516d13bafd",
   "metadata": {},
   "source": [
    "## Data Model\n",
    "\n",
    "**Note** The data model being used has been covered in [Intro to Software Bill Of Materials](./00-Intro-to-Software-Bill-Of-Materials.ipynb), so please read that to get a deeper understanding of the summary presented below.\n",
    "\n",
    "![image.png](attachment:image.png)\n",
    "\n",
    "**Node Types**\n",
    "* `Document` - This represents the SBOM document as well as the metadata associated with that SBOM.\n",
    "* `Component` - This represents a specific component of a software system.\n",
    "* `Reference` - This represents a reference to any external system which the system wanted to include as a reference.  This can range from package managers, URLs to external websites, etc.\n",
    "* `Vulnerability` - This represents a specific known vulnerability for a component. \n",
    "* `License` - This represents a specific license associated for a component.\n",
    "\n",
    "**Edge Types**\n",
    "* `DESCRIBES`/`DEPENDS_ON`/`DEPENDENCY_OF`/`DESCRIBED_BY`/`CONTAINS` - This represents the type of relationship between a `Document` and a `Component` in the system. \n",
    "* `REFERS_TO` - This represents a reference between a `Component` and a `Reference`\n",
    "* `AFFECTS` - This represents that a particular `Component` is affected by the connected `Vulnerability`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c405d964-1ceb-47c2-835b-7146a18842d3",
   "metadata": {},
   "source": [
    "## Loading SBOM Data\n",
    "\n",
    "In this notebook we will use [Nodestream](https://nodestream-proj.github.io/docs/) and the [Nodestream SBOM plugin](https://github.com/nodestream-proj/nodestream-plugin-sbom) to load several SPDX files which were sourced from Github using its SBOM feature, detailed [here](https://docs.github.com/en/rest/dependency-graph/sboms).  \n",
    "\n",
    "Nodestream is a framework for dealing with semantically modeling data as a graph. It is designed to be flexible and extensible, allowing you to define how data is collected and modeled as a graph. It uses a pipeline-based approach to define how data is collected and processed, and it provides a way to define how the graph should be updated when the schema changes. All of this is done using a simple, human-readable configuration file in yaml format.\n",
    "\n",
    "Let's begin by installing the required libraries for using Nodestream with Neptune and the SBOM plugin."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82ba85df-017a-4eaa-b274-b222523c4ee4",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "!pip install -q pyyaml nodestream-plugin-neptune nodestream_plugin_sbom"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1e96f3d-b637-4fd4-a3de-a2bcfce869ec",
   "metadata": {
    "tags": []
   },
   "source": [
    "\n",
    "The SBOM plugin enables users to import SBOM files in JSON formatted CycloneDX and SPDX into an opinionated graph data model in a graph database. Nodestream is a developer friendly Python framework for materializing and working with graph databases.\n",
    "\n",
    "The included files for this notebook are:\n",
    "\n",
    "* [AWS Graph Explorer](https://github.com/aws/graph-explorer)\n",
    "* [Graph Notebook](https://github.com/aws/graph-notebook)\n",
    "* [AWS SDK For pandas](https://github.com/aws/aws-sdk-pandas)\n",
    "* [boto3](https://github.com/boto/boto3)\n",
    "\n",
    "<div class=\"alert alert-block alert-info\"> \n",
    "<details>\n",
    "    <summary>✏️<b><i> Click here for a tip</i></b></summary>\n",
    "  \n",
    "If you would like to import your own SBOM files, you can either save them in JSON format to the `./example_sboms/01/` directory, or change the directory location in the code below.\n",
    "</details>\n",
    "</div>\n",
    "\n",
    "Running the cell below will setup our configuration file for loading our SBOM data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "91e7ea13-521a-4f34-bdbd-d9f8791fa978",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import json\n",
    "from IPython.utils import io\n",
    "from sbom_code import sbom_helper\n",
    "\n",
    "# Retrieve the notebook configuration information to pass in as parameters and supress printing the config\n",
    "with io.capture_output() as captured:\n",
    "    mgc = get_ipython().run_line_magic\n",
    "    mgc(magic_name = \"graph_notebook_config\", line=\"--store-to config\")\n",
    "\n",
    "# Create the nodestream.yaml file\n",
    "sbom_helper.set_nodesteam_yaml(json.loads(config), \"01/\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d60ba7ac-4d3a-47ef-9671-e357acb3a91e",
   "metadata": {
    "tags": []
   },
   "source": [
    "Running the code above will generate a `nodestream.yaml` file that specifies the source data and target, which in this case is our Neptune database or graph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ccb4d774-6fd3-4ed5-8601-a92bb8a3c339",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "!nodestream run sbom --target my-neptune"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8630fc3-c3f8-456c-820a-8b254f9f164e",
   "metadata": {},
   "source": [
    "## Dependency Management\n",
    "\n",
    "Now that we have completed importing these SBOM files, let's begin by visualizing the graph of components in the SBOM.\n",
    "\n",
    "### Graph of components for the `graph-notebook`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1a4533b2-7ef9-48ac-b7f3-759adcc0b544",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc  -d name\n",
    "\n",
    "MATCH p=(n:Document {name: 'com.github.aws/graph-notebook'})-[]->()\n",
    "RETURN p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05a38fe4-02ba-435a-b1dc-f36919e332bb",
   "metadata": {},
   "source": [
    "Now, let's take a look at the entire SBOM for this project.\n",
    "\n",
    "### Graph of entire SBOM for the `graph-notebook`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5f52d7a8-4a11-4ddf-b6f5-7e4c8b760721",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -d name\n",
    "\n",
    "MATCH p=(n:Document {name: 'com.github.aws/graph-notebook'})-[*1..2]->()\n",
    "RETURN p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0ee4f37-9d5b-4ba2-9e8e-e949ef1c0d88",
   "metadata": {},
   "source": [
    "## Shared Dependencies\n",
    "\n",
    "Another common use case with multiple SBOM's is to analyze and investigate shared dependencies across projects.  Shared dependencies allow development and security teams to better understand the security posture of the organization through identification of shared risks.  Let's start by taking a look at all the shared dependencies between these projects.\n",
    "\n",
    "### Viewing shared dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21bbb65b-f771-4bf2-b771-1d3a01edd8fe",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -d name\n",
    "\n",
    "MATCH p=(d1:Document)-[r]->(c:Component)<-[]-(d2:Document)\n",
    "WHERE d1 <> d2\n",
    "RETURN p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b122546-58b1-4691-947c-f2a9195205a8",
   "metadata": {},
   "source": [
    "Now, let's take a look at the top 10 most shared dependencies.\n",
    "\n",
    "### Which is the most shared dependency"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3398a81-4efc-452e-9f3b-ba9caa066e06",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%oc --store-to degree_data\n",
    "\n",
    "MATCH (n:Component)\n",
    "WHERE exists(n.name)\n",
    "CALL neptune.algo.degree(n, {traversalDirection: 'both', edgeLabels: ['DEPENDS_ON']})\n",
    "YIELD node, degree\n",
    "RETURN node.name, degree\n",
    "ORDER BY degree DESC \n",
    "LIMIT 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84acd344-132f-469d-b4e5-a6a3838adda0",
   "metadata": {},
   "source": [
    "Now that we know the most often shared dependency, let's take a look at the projects that share this dependency.\n",
    "\n",
    "### Let's investigate this shared dependency's connections"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a31ff0d9-da3e-4c54-9d08-b84b2c2869e3",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "params = {'name': degree_data['results'][0]['node.name']}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19ae58cb-6125-431a-882e-d89bf71d24ec",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -qp params -d name\n",
    "\n",
    "MATCH p=(n: Component {name: $name})<-[:DEPENDS_ON]-()\n",
    "RETURN p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "139c53c7-0fcd-4117-9696-e9a483486ad1",
   "metadata": {},
   "source": [
    "As we see, all four of our projects depend on the same component.  This sort of information is valuable during development and maintenance to prevent out-of-date or vulnerable components from entering the software supply chain."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04171082-c883-4679-8956-303d21da09b1",
   "metadata": {},
   "source": [
    "## Cyclic Dependencies\n",
    "\n",
    "Cyclic dependencies refer to situations where two or more components depend on each other in a circular fashion. For example, component A depends on component B, which in turn depends on component C, which then depends back on component A.\n",
    "\n",
    "Identifying cyclic dependencies is important for a few reasons:\n",
    "\n",
    "* It highlights potential design issues - cyclic dependencies make code more tightly coupled and harder to maintain.\n",
    "\n",
    "* It impacts security vulnerability analysis - if one component has a vulnerability, all cyclically dependent components could be impacted.\n",
    "\n",
    "* It aids refactoring and restructuring efforts - breaking down cyclic groups into more hierarchical structures.\n",
    "\n",
    "Overall, analyzing cyclical dependencies in SBOMs provides insights into the architecture, security, and license compliance of large modern applications with many interconnected components. Removing cycles when possible leads to more resilient and sustainable software.\n",
    "\n",
    "To identify cyclic dependencies in an SBOM, we can leverage the fact that a well designed application will contain components that make up a [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph).  A directed graph is acyclic if and only if it has no strongly connected subgraphs with more than one vertex.  A directed cycle is strongly connected and every non-trivial strongly connected component contains at least one directed cycle.  We can leverage a graph algorithm known as [Strongly Connected Components](https://docs.aws.amazon.com/neptune-analytics/latest/userguide/scc.html) to test for these within our graph.  In this scenario, we would expect that every component returned would only contain a single node."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b2a537d-8224-4dc1-9f42-95500ac908dd",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc \n",
    "\n",
    "MATCH (n) \n",
    "WHERE NOT n:Reference\n",
    "CALL neptune.algo.scc(n)\n",
    "YIELD node, component\n",
    "WITH component, count(node) as cnt\n",
    "WHERE cnt>1\n",
    "RETURN component"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2486dee-eb90-4318-a2d3-9cf3904e1cb6",
   "metadata": {},
   "source": [
    "## Next Steps\n",
    "\n",
    "In this notebook, we have demonstrated how to perform Dependency Analysis on SBOMs using Neptune Analytics.  While this notebook used a set of specific SBOM files, the code provided by the Nodestream SBOM plugin may also be used to load your own SBOM files, including code from Github as well as directly from Amazon Inspector.  \n",
    "\n",
    "Please look at how to configure and run these import in the [SBOM Plugin - Running Pipelines](https://github.com/nodestream-proj/nodestream-plugin-sbom/?tab=readme-ov-file#running-pipelines).\n",
    "\n",
    "If you are interested in the other types of SBOM analysis please look at the other notebooks available:\n",
    "\n",
    "* [SBOM Vulnerability Analysis](./02-SBOM-Vulnerability-Analysis.ipynb)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
